from Data import search_file
import os
import shutil
import fitz  # PyMuPDF


# 主函数，pdf合并
def pdf_collaboration_en(selected_function):
    root_path = None
    filepaths = search_file.select_folder()
    if filepaths == "-1":
        return "-1"
    else:
        count = 0
        for path in filepaths:
            if "01-配置指南" in path.split('\\')[-3]:
                if count == 0:
                    root_path = path.rsplit("01-配置指南", 1)[0]
                    scg_path = f'{path.rsplit("01-配置指南", 1)[0]}01-配置指南\\00-pdf'
                    # 检查并创建配置指南输出目录
                    if not os.path.exists(scg_path):
                        os.makedirs(scg_path)
                        print(scg_path)
                count = count + 1
            if "02-命令参考" in path.split('\\')[-3]:
                cref_path = f'{path.rsplit("02-命令参考", 1)[0]}02-命令参考\\00-pdf'
                if not os.path.exists(cref_path):
                    os.makedirs(cref_path)
                    print(cref_path)
                break
        # 检查根路径是否存在
        if None == root_path:
            print(f"错误：找不到根路径")
            print("请检查配置指南与命令参考编号")
            print("程序执行完成!!!")
            return "-1"
        if selected_function == "SCG/CREF合稿":
            directory_mapping(filepaths, scg_path, cref_path)
            convert_to_pdf_format(scg_path, cref_path, root_path)
            print("程序执行完成!!!")
        if selected_function == "大本合稿":
            convert_to_pdf_format(scg_path, cref_path, root_path)
            print("程序执行完成!!!")


# 目录映射
def directory_mapping(filepaths, scg_path, cref_path):
    directory_map = {}
    for filepath in filepaths:
        parts = filepath.split('\\')
        if len(parts) >= 4:
            # 修改目录层级判断
            # if "封面" in parts[-2] or "扉页" in parts[-2]:
            #     cover_and_title_page = True
            #     first_level = parts[-2]  # 封面和扉页作为一级目录
            #     second_level = None  # 使用文件名作为二级标识
            # else:
            first_level = parts[-3]  # 其他情况按原来的逻辑处理
            second_level = parts[-2]

            # 初始化一级目录
            if first_level not in directory_map:
                directory_map[first_level] = {}
            # 将文件添加到对应的二级目录
            if second_level not in directory_map[first_level]:
                directory_map[first_level][second_level] = []
            directory_map[first_level][second_level].append(filepath)

    # 处理每个目录
    for first_level, second_levels in directory_map.items():
        for second_level, files in second_levels.items():
            # print(first_level,second_levels)
            # if None == second_level:
            if "封面" in first_level and "扉页" in first_level:
                # 将文件copy到00-pdf
                print(f"\033[93m正在处理: {first_level}->{second_level}\033[0m")
                copy_the_cover_and_title_page(files, scg_path, cref_path, first_level, 0)
            if "配置指南" in first_level or "命令参考" in first_level:
                if "00-封面" == second_level:
                    print(f"\033[93m正在处理: {first_level}->{second_level}\033[0m")
                    copy_the_cover_and_title_page(files, scg_path, cref_path, first_level, 1)
                if "00-pdf" != second_level and "00-封面" != second_level:
                    print(f"\033[93m正在处理: {first_level}->{second_level}\033[0m")
                    merge_pdf_volumes(files, second_level, scg_path, cref_path, first_level)


# 分册pdf合并
def merge_pdf_volumes(files, second_level, scg_path, cref_path, first_level):
    try:
        merged_pdf = fitz.open()
        page_offset = 0
        all_bookmarks = []

        for file in files:
            try:
                with fitz.open(file) as pdf:
                    if pdf.page_count == 0:
                        continue

                    # 获取文件名作为一级书签
                    file_name = os.path.basename(file).replace('.pdf', '')
                    first_bookmark = [1, file_name, page_offset + 1]
                    all_bookmarks.append(first_bookmark)

                    # 复制文档
                    merged_pdf.insert_pdf(pdf)

                    # 获取原始书签并处理
                    original_toc = pdf.get_toc(simple=False)  # 获取完整书签信息
                    if original_toc:
                        for bookmark in original_toc:
                            level, title, page, dest = bookmark[:4]
                            if dest:
                                # 提取目标页面和位置信息
                                dest_page = dest.get('page', page - 1)
                                dest_top = dest.get('to', fitz.Point(0, 0)).y
                                # 创建新的书签项，包含精确位置信息
                                adjusted_bookmark = [
                                    level + 1,  # 增加层级，因为文件名是一级
                                    title,
                                    dest_page + page_offset + 1,
                                    {
                                        "kind": 1,
                                        "page": dest_page + page_offset,
                                        "to": fitz.Point(0, dest_top),
                                        "zoom": 0
                                    }
                                ]
                                all_bookmarks.append(adjusted_bookmark)

                    page_offset += pdf.page_count

            except Exception as e:
                print(f"处理文件 {file} 时出错: {str(e)}")
                continue

        # 检查并设置书签
        if len(merged_pdf) > 0 and all_bookmarks:
            try:
                merged_pdf.set_toc(all_bookmarks)
                print(f"成功设置 {len(all_bookmarks)} 个书签")
            except Exception as e:
                print(f"设置书签时出错: {str(e)}")

        # 确定输出路径和保存
        # 判断是否包含中文
        if any('\u4e00' <= char <= '\u9fff' for char in second_level):
            name = volume_name(second_level, True, first_level)
            if "配置指南" in first_level:
                output_path = os.path.join(scg_path, f"{name}.pdf")
            else:
                output_path = os.path.join(cref_path, f"{name}.pdf")
        else:
            name = volume_name(second_level, False, first_level)
            if "配置指南" in first_level:
                output_path = os.path.join(scg_path, f"{name}.pdf")
            else:
                output_path = os.path.join(cref_path, f"{name}.pdf")
        merged_pdf.save(output_path, garbage=4, clean=True, deflate=True)
        merged_pdf.close()
        print(f"已合并PDF文件: {output_path}")

    except Exception as e:
        print(f"合并PDF文件失败: {str(e)}")


def volume_name(second_level, flag, first_level):
    num = second_level.split('-')[0]
    file_name_metadata = [['基础配置', f'{num}-Basic Configuration'],
                          ['设备管理', f'{num}-Alarm Management'],
                          ['接口', f'{num}-Interface'],
                          ['虚拟化', f'{num}-Virtualization'],
                          ['以太网交换', f'{num}-Ethernet Switching'],
                          ['IP业务', f'{num}-IP Service'],
                          ['IP路由', f'{num}-IP Routing'],
                          ['组播', f'{num}-Multicast'],
                          ['MPLS', f'{num}-MPLS'],
                          ['ACL和QoS', f'{num}-ACL and QoS'],
                          ['安全', f'{num}-Security'],
                          ['可靠性', f'{num}-Reliability'],
                          ['网管与监控', f'{num}-Network Control and Monitoring'],
                          ['无损网络', f'{num}-Lossless Network'],
                          ['VPN', f'{num}-VPN'],
                          ['数据中心', f'{num}-Data Center'],
                          ]
    if flag:
        for filename in file_name_metadata:
            if filename[0] in second_level:
                return filename[1]
    else:
        if "配置指南" in first_level:
            if "Basic Configuration" in second_level:
                return f"{num}-Basic Configuration"
            else:
                return second_level.split(" Configuration")[0]
        if "命令参考" in first_level:
            if "Basic Commands" in second_level:
                return f"{num}-Basic Configuration"
            else:
                return second_level.split(" Commands")[0]


# 复制封面扉页
def copy_the_cover_and_title_page(files, scg_path, cref_path, first_level, num):
    if num == 1:
        for file in files:
            try:
                original_name = os.path.basename(file)

                if "命令参考" in first_level:
                    target_file = os.path.join(cref_path, original_name)
                    if os.path.exists(target_file):
                        os.remove(target_file)
                    shutil.copy2(file, target_file)
                    print(f"已复制封面扉页文件到命令参考: {target_file}")

                if "配置指南" in first_level:
                    target_file = os.path.join(scg_path, original_name)
                    if os.path.exists(target_file):
                        os.remove(target_file)
                    shutil.copy2(file, target_file)
                    print(f"已复制封面扉页文件到配置指南: {target_file}")

            except Exception as e:
                print(f"\033[31m处理文件失败: {str(e)}\033[0m")
    else:
        for file in files:
            try:
                scg_cref = file.rsplit("\\")[-2]
                original_name = os.path.basename(file)

                if "命令" in scg_cref:
                    target_file = os.path.join(cref_path, original_name)
                    if os.path.exists(target_file):
                        os.remove(target_file)
                    shutil.copy2(file, target_file)
                    print(f"已复制封面扉页文件到命令参考: {target_file}")

                if "配置" in scg_cref:
                    target_file = os.path.join(scg_path, original_name)
                    if os.path.exists(target_file):
                        os.remove(target_file)
                    shutil.copy2(file, target_file)
                    print(f"已复制封面扉页文件到配置指南: {target_file}")

            except Exception as e:
                print(f"\033[31m处理文件失败: {str(e)}\033[0m")


# 转pdf大本
def convert_to_pdf_format(scg_path, cref_path, path):
    try:
        # 处理配置指南和命令参考
        for doc_type, input_path in [("Configuration Guide", scg_path), ("Command Reference", cref_path)]:
            print(f"\033[93m正在合并{doc_type}：\033[0m")
            merged_pdf = fitz.open()
            page_offset = 0
            all_bookmarks = []
            current_parent_level = 1

            # 获取所有PDF文件并排序
            pdf_files = []
            cover_file = os.path.join(input_path, "Title cover.pdf")
            title_page_file = os.path.join(input_path, "Title page.pdf")

            # 添加封面和扉页
            if os.path.exists(cover_file):
                pdf_files.append(cover_file)
            if os.path.exists(title_page_file):
                pdf_files.append(title_page_file)

            # 获取其他PDF文件并按数字排序
            other_files = [f for f in os.listdir(input_path)
                           if f.endswith('.pdf')
                           and f not in ["Title cover.pdf", "Title page.pdf"]]
            other_files.sort(key=lambda x: int(''.join(filter(str.isdigit, x)) or '0'))
            pdf_files.extend([os.path.join(input_path, f) for f in other_files])

            # 合并所有PDF文件
            for file in pdf_files:
                try:
                    with fitz.open(file) as pdf:
                        if pdf.page_count == 0:
                            continue

                        # 获取文件名作为书签
                        file_name = os.path.basename(file).replace('.pdf', '')

                        # 添加文件名作为一级书签
                        first_bookmark = [1, file_name, page_offset + 1]
                        all_bookmarks.append(first_bookmark)
                        current_parent_level = 1

                        # 复制文档
                        merged_pdf.insert_pdf(pdf)

                        # 获取并处理原始书签
                        original_toc = pdf.get_toc(simple=False)
                        if original_toc:
                            for bookmark in original_toc:
                                level, title, page, dest = bookmark[:4]
                                if dest:
                                    # 提取目标页面和位置信息
                                    dest_page = dest.get('page', page - 1)
                                    dest_top = dest.get('to', fitz.Point(0, 0)).y

                                    # 调整书签层级
                                    adjusted_level = level + current_parent_level

                                    # 创建新的书签项
                                    adjusted_bookmark = [
                                        adjusted_level,
                                        title,
                                        dest_page + page_offset + 1,
                                        {
                                            "kind": 1,
                                            "page": dest_page + page_offset,
                                            "to": fitz.Point(0, dest_top),
                                            "zoom": 0
                                        }
                                    ]
                                    all_bookmarks.append(adjusted_bookmark)

                        page_offset += pdf.page_count

                except Exception as e:
                    print(f"处理文件 {file} 时出错: {str(e)}")
                    continue

            # 设置书签
            if len(merged_pdf) > 0 and all_bookmarks:
                try:
                    merged_pdf.set_toc(all_bookmarks)
                    print(f"成功设置 {len(all_bookmarks)} 个书签")
                except Exception as e:
                    print(f"设置书签时出错: {str(e)}")

            # 保存合并后的文件
            output_path = os.path.join(path, f"{doc_type} (V1.0).pdf")
            merged_pdf.save(output_path, garbage=4, clean=True, deflate=True)
            merged_pdf.close()
            print(f"已生成{doc_type}合集: {output_path}")

    except Exception as e:
        print(f"合并文档失败: {str(e)}")


if __name__ == '__main__':
    pdf_collaboration_en("SCG/CREF合稿")
